package com.yuyou.fn.educational.service.impl;

import com.github.wens.framework.service.impl.SuperServiceImpl;
import com.github.wens.mybatisplus.examples.Example;
import com.github.wens.mybatisplus.plugins.Page;
import com.yuyou.fn.common.constant.ClassLevelEnum;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.util.*;
import com.yuyou.fn.educational.entity.*;
import com.yuyou.fn.educational.mapper.CourseTemplateMapper;
import com.yuyou.fn.educational.service.*;
import com.yuyou.fn.educational.vo.CourseTemplateQueryVo;
import com.yuyou.fn.educational.vo.CourseTemplateSaveOrUpdateVo;
import com.yuyou.fn.platform.entity.AreaTeam;
import com.yuyou.fn.platform.entity.SysUser;
import com.yuyou.fn.platform.permission.DataPermission;
import com.yuyou.fn.platform.service.IAreaTeamService;
import com.yuyou.fn.platform.service.IBusTeamService;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * CourseTemplate 表数据服务层接口实现类
 */
@Service
public class CourseTemplateServiceImpl extends SuperServiceImpl<CourseTemplateMapper, CourseTemplate, Long> implements ICourseTemplateService {

    @Resource
    private ICourseTypeService courseTypeService;

    @Resource
    private IAreaTeamService areaTeamService;

    @Resource
    private IBusTeamService busTeamService;

    @Resource
    private IBaseGradeService baseGradeService;

    @Resource
    private IBaseSubjectService baseSubjectService;

    @Resource
    private IPeriodService periodService;

    @Resource
    private IProductService productService ;

    @Resource
    private ICourseClassService courseClassService ;



    @Override
    public Page<CourseTemplate> findCourseTemplateByQueryForManage(CourseTemplateQueryVo courseTemplateQuery, DataPermission dataPermission, int pageNo, int pageSize) {
        Example<CourseTemplate> example = CourseTemplate.createExample();
        example.orderBy("createTime").desc();
        Example.Criteria criteria = example.createCriteria();
        CriteriaUtils.fillCondition(criteria, courseTemplateQuery);
        if(dataPermission.getUserType() == 0 || dataPermission.getUserType() == 1 ){
            CriteriaUtils.fillConditionForAreaTeamPermission(criteria,dataPermission.getAreaTeamIds());
        }else{
            CriteriaUtils.fillConditionForBusPermission(criteria,dataPermission.getBusTeamIds());
        }
        return findPageByExample(example, pageNo, pageSize);
    }

    @Override
    public SXSSFWorkbook exportCourseTemplateByQueryForManage(CourseTemplateQueryVo courseTemplateQuery, DataPermission dataPermission) {
        Page<CourseTemplate> page=this.findCourseTemplateByQueryForManage(courseTemplateQuery,dataPermission,1,50000);
        return exportCourseTemplateByQueryForManage(page.getRecords());
    }

    public static SXSSFWorkbook exportCourseTemplateByQueryForManage(List<CourseTemplate> courseTemplateList) {

        SXSSFWorkbook excel = new SXSSFWorkbook();
        SXSSFSheet sheet = excel.createSheet("课程列表");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{"课程名","课程类型","年级","科目",	"讲数","班型",	"区域",	"业务组","期数"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum=1;
        for (CourseTemplate courseTemplate:courseTemplateList){
            int cellNum = 0;
            SXSSFRow row = sheet.createRow(rowNum++);

            SXSSFCell cell = row.createCell(cellNum++);
            cell.setCellValue(StringUtils.defaultString(courseTemplate.getCourseName()));

            cell = row.createCell(cellNum++);
            cell.setCellValue(StringUtils.defaultString(courseTemplate.getCourseTypeName()));

            cell = row.createCell(cellNum++);
            cell.setCellValue(StringUtils.defaultString(courseTemplate.getGradeName()));

            cell = row.createCell(cellNum++);
            cell.setCellValue(StringUtils.defaultString(courseTemplate.getSubjectName()));

            cell = row.createCell(cellNum++);
            cell.setCellValue(courseTemplate.getLectureAmount());

            cell = row.createCell(cellNum++);
            cell.setCellValue(EnumUtils.getName(ClassLevelEnum.values(),courseTemplate.getLevel()));

            cell = row.createCell(cellNum++);
            cell.setCellValue(StringUtils.defaultString(courseTemplate.getAreaTeamName()));

            cell = row.createCell(cellNum++);
            cell.setCellValue(StringUtils.defaultString(courseTemplate.getBusTeamName()));

            cell = row.createCell(cellNum++);
            cell.setCellValue(StringUtils.defaultString(courseTemplate.getPeriodName()));

        }
        return excel;
    }




    @Override
    public Page<CourseTemplate> findCourseTemplateByQueryForUse(CourseTemplateQueryVo courseTemplateQuery, DataPermission dataPermission, int pageNo, int pageSize) {
        Example<CourseTemplate> example = CourseTemplate.createExample();
        example.orderBy("createTime").desc();
        Example.Criteria criteria = example.createCriteria();
        CriteriaUtils.fillCondition(criteria, courseTemplateQuery);
        CriteriaUtils.fillConditionForAreaTeamPermission(criteria,dataPermission.getAreaTeamIds());
        return findPageByExample(example, pageNo, pageSize);
    }

    @Override
    public List<CourseTemplate> findCourseTemplateByQuery(CourseTemplateQueryVo courseTemplateQuery){
        Example<CourseTemplate> example = CourseTemplate.createExample();
        example.orderBy("createTime").desc();
        Example.Criteria criteria = example.createCriteria();
        CriteriaUtils.fillCondition(criteria, courseTemplateQuery);

        return findListByExample(example);

    }

    @Override
    public void saveOrUpdateCourseTemplateList(CourseTemplateSaveOrUpdateVo courseTemplateSaveOrUpdateVo) {

        CourseTemplate courseTemplate = new CourseTemplate();

        BeanUtils.copyProperties(courseTemplate, courseTemplateSaveOrUpdateVo);
        checkCourse(courseTemplate);
        fillExtraData(courseTemplate);

        saveOrUpdate(courseTemplate);
    }

    private void checkCourse(CourseTemplate courseTemplate) {
        /*Example<CourseTemplate> example = CourseTemplate.createExample();
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("areaTeamId",courseTemplate.getAreaTeamId()).andEqualTo("courseName" , courseTemplate.getCourseName() );

        CourseTemplate one = findOneByExample(example);
        if(one != null && ( courseTemplate.getCourseTemplateId() == null || !one.getCourseTemplateId().equals(courseTemplate.getCourseTemplateId()))){
            throw new BusException("课程名重复");
        }*/
    }

    @Override
    public void changeCourseStatus(Long courseTemplateId, Integer status) {

        if (status != 0 && status != 1) {
            throw new IllegalArgumentException("Invalid status");
        }

        CourseTemplate courseTemplate = new CourseTemplate();
        courseTemplate.setCourseTemplateId(courseTemplateId);
        courseTemplate.setStatus(status);
        updateSelectiveById(courseTemplate);

    }

    @Override
    public List<CourseTemplate> findBaseCourse(DataPermission dataPermission) {
        Example<CourseTemplate> example = CourseTemplate.createExample();
        Example.Criteria criteria = example.createCriteria();
        example.selectProperties("courseName");
        CriteriaUtils.fillConditionForAreaTeamPermission(criteria,dataPermission.getAreaTeamIds());
        return findListByExample(example);
    }

    @Transactional
    @Override
    public void saveOrUpdateCourseTemplateList(List<CourseTemplate> courseTemplateList,SysUser user) {
        if ( courseTemplateList.size()!=0){

            List<String> seasons = Arrays.asList("春季班","暑期班","秋季班","寒假班");
            List<Integer>  levels = Arrays.asList(1 ,2 ,3,4,5 );

            for (CourseTemplate courseTemplate : courseTemplateList) {

                String areaTeamName = courseTemplate.getAreaTeamName();
                AreaTeam areaTeam = areaTeamService.findAreaTeamByName(areaTeamName);

                if(areaTeam == null ){
                    throw new BusException("无法识别区域：" + areaTeamName );
                }

                courseTemplate.setAreaTeamId(areaTeam.getAreaTeamId());
                courseTemplate.setBusTeamId(0l);
                courseTemplate.setAreaTeamName(areaTeam.getName());
                courseTemplate.setBusTeamName("");


                String gradeName = courseTemplate.getGradeName();
                BaseGrade baseGrade = baseGradeService.findGradeByGradeName(gradeName);
                if(baseGrade == null ){
                    throw new BusException("无法识别年级：" + gradeName );
                }
                courseTemplate.setGradeId(baseGrade.getGradeId());
                String subjectName = courseTemplate.getSubjectName();
                BaseSubject subject = baseSubjectService.findSubjectBySubjectName(subjectName);
                if(subject == null ){
                    throw new BusException("无法识别科目：" + subjectName );
                }
                courseTemplate.setSubjectId(subject.getSubjectId());

                String productName = courseTemplate.getProductName();
                Product product = productService.findProductByNameAreaTeamId(productName,courseTemplate.getAreaTeamId() );
                if(product == null ){
                    throw new BusException("无法识别产品名：" + productName );
                }
                courseTemplate.setProductId(product.getProductId());
                String courseTypeName = courseTemplate.getCourseTypeName();
                CourseType courseType = courseTypeService.findCourseTypeByName(courseTypeName);
                if(courseType == null ){
                    throw new BusException("无法识别课程类型：" + courseTypeName );
                }
                courseTemplate.setCourseTypeId(courseType.getCourseTypeId());


                if(!levels.contains(courseTemplate.getLevel())){
                    throw new BusException("无法层级：" + courseTemplate.getLevel() );
                }

                this.saveOrUpdate(courseTemplate);
            }
        }else{
            throw new BusException("请检查导入文件");
        }
    }


    private void saveOrUpdate(CourseTemplate courseTemplate) {
        checkCourse(courseTemplate);
        if (courseTemplate.getCourseTemplateId() == null) {
            courseTemplate.setCreateTime(TimeUtils.now());
            courseTemplate.setUpdateTime(TimeUtils.now());
            insertSelective(courseTemplate);
        } else {
            courseTemplate.setUpdateTime(TimeUtils.now());
            updateSelectiveById(courseTemplate);
        }
    }

    private void fillExtraData(CourseTemplate courseTemplate) {

        if (courseTemplate.getAreaTeamId() != null) {
            courseTemplate.setAreaTeamName(areaTeamService.findTeamNameById(courseTemplate.getAreaTeamId()));
        } else {
            courseTemplate.setAreaTeamId(0l);
            courseTemplate.setAreaTeamName("");
        }
        if (courseTemplate.getPeriodId()!=null){
            courseTemplate.setPeriodName(periodService.findById(courseTemplate.getPeriodId()).getPeriodName());
        }

        if (courseTemplate.getBusTeamId() != null) {
            courseTemplate.setBusTeamName(busTeamService.findTeamNameById(courseTemplate.getBusTeamId()));
        } else {
            courseTemplate.setBusTeamId(0l);
            courseTemplate.setBusTeamName("");
        }

        if (courseTemplate.getCourseTypeId() != null) {
            courseTemplate.setCourseTypeName(courseTypeService.findCourseTypeNameById(courseTemplate.getCourseTypeId()));
        } else {
            courseTemplate.setCourseTypeId(0l);
            courseTemplate.setCourseTypeName("");
        }

        if (courseTemplate.getGradeId() != null) {
            courseTemplate.setGradeName(baseGradeService.findGradeNameById(courseTemplate.getGradeId()));
        } else {
            courseTemplate.setGradeId(0l);
            courseTemplate.setGradeName("");
        }

        if (courseTemplate.getSubjectId() != null) {
            courseTemplate.setSubjectName(baseSubjectService.findGradNameById(courseTemplate.getSubjectId()));
        } else {
            courseTemplate.setSubjectId(0l);
            courseTemplate.setSubjectName("");
        }
        if (courseTemplate.getProductId()!=null) {
            courseTemplate.setProductName(productService.findProductNameById(courseTemplate.getProductId()));
        } else {
            courseTemplate.setProductId(0l);
            courseTemplate.setProductName("");
        }

    }

    @Override
    public void deleteCourse(Long courseTemplateId) {

        Example<CourseClass> courseClassExample = CourseClass.createExample();

        courseClassExample.createCriteria().andEqualTo("courseTemplateId",courseTemplateId);

        long l = courseClassService.countByExample(courseClassExample);

        if(l > 0 ){
            throw new BusException("课程类型在已被应用的情况下无法删除。");
        }
        deleteById(courseTemplateId);
    }

    @Override
    public List<CourseTemplate> findBaseCourseByAreaTeamId(Long areaTeamId) {
        Example<CourseTemplate> example = CourseTemplate.createExample();
        example.selectProperties("courseName");
        example.createCriteria().andEqualTo("areaTeamId" , areaTeamId );
        return findListByExample(example);
    }

    @Override
    public List<CourseTemplate> findBaseCourseByAreaTeamIdPeriodIds(Long areaTeamId, List<Long> periodIds) {
        if (Utils.checkListEmpty(periodIds)){
            return Collections.EMPTY_LIST;
        }
        Example<CourseTemplate> example = CourseTemplate.createExample();
        example.selectProperties("courseName");
        example.createCriteria().andEqualTo("areaTeamId" , areaTeamId ).andIn("periodId",periodIds);
        return findListByExample(example);
    }

    @Override
    public CourseTemplate findCourseByAreaTeamIdGradeIdSubjectIdCourseNamePeriodIdProductId(Long areaTeamId , Long gradeId , Long subjectId , String courseName, Long periodId,Long productId) {
        Example<CourseTemplate> example = CourseTemplate.createExample();
        example.createCriteria().andEqualTo("areaTeamId" , areaTeamId ).andEqualTo("gradeId" , gradeId).andEqualTo("subjectId" , subjectId ).andEqualTo("courseName" ,courseName ).andEqualTo("periodId",periodId).andEqualTo("productId",productId);
        return findOneByExample(example);
    }
}